/****************************************************************/
/*																*/
/*  UserManager.cpp												*/
/*																*/
/*  Implementation of the CUserManager class.					*/
/*	This class is a part of Quick 'n Easy FTP Server.			*/
/*																*/
/*  Programmed by Pablo van der Meer							*/
/*  Copyright Pablo Software Solutions 2005						*/
/*	http://www.pablosoftwaresolutions.com						*/
/*																*/
/*  Last updated: May 28, 2005									*/
/*																*/
/****************************************************************/


#include "stdafx.h"
#include "FTPserverApp.h"
#include "UserManager.h"

extern CFTPServerApp theApp;

IMPLEMENT_SERIAL(CUser, CObject, 1)


/********************************************************************/
/*																	*/
/* Function name : CUser											*/
/* Description   : Constructor										*/
/*																	*/
/********************************************************************/
CUser::CUser()
{
	m_bAccountDisabled = FALSE;

	m_bAllowDownload = TRUE;
	m_bAllowUpload = FALSE;
	m_bAllowRename = FALSE;
	m_bAllowDelete = FALSE;
	m_bAllowCreateDirectory = FALSE;
}


/********************************************************************/
/*																	*/
/* Function name : ~CUser											*/
/* Description   : Destructor										*/
/*																	*/
/********************************************************************/
CUser::~CUser()
{
}


/********************************************************************/
/*																	*/
/* Function name : Serialize										*/
/* Description   : Store/load user properties						*/
/*																	*/
/********************************************************************/
void CUser::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// 'store' data
		ar << m_strName;
		ar << m_strPassword;
		ar << m_bAccountDisabled;

		ar << m_strHomeDirectory;
		ar << m_bAllowDownload;
		ar << m_bAllowUpload;
		ar << m_bAllowRename;
		ar << m_bAllowDelete;
		ar << m_bAllowCreateDirectory;
	}
	else
	{
		// 'load' data
		ar >> m_strName;
		ar >> m_strPassword;
		ar >> m_bAccountDisabled;

		ar >> m_strHomeDirectory;
		ar >> m_bAllowDownload;
		ar >> m_bAllowUpload;
		ar >> m_bAllowRename;
		ar >> m_bAllowDelete;
		ar >> m_bAllowCreateDirectory;
	}
}


/********************************************************************/
/*																	*/
/* Function name : CUser											*/
/* Description   : Copy-constructor									*/
/*																	*/
/********************************************************************/
CUser::CUser(const CUser &user)
{
	m_strName = user.m_strName;
	m_strPassword = user.m_strPassword;
	m_bAccountDisabled = user.m_bAccountDisabled;

	m_strHomeDirectory = user.m_strHomeDirectory;
	m_bAllowDownload = user.m_bAllowDownload;
	m_bAllowUpload = user.m_bAllowUpload;
	m_bAllowRename = user.m_bAllowRename;
	m_bAllowDelete = user.m_bAllowDelete;
	m_bAllowCreateDirectory = user.m_bAllowCreateDirectory;
}

/********************************************************************/
/*																	*/
/* Function name : CUser											*/
/* Description   : = operator definition 							*/
/*																	*/
/********************************************************************/
CUser& CUser::operator=(const CUser &user)
{
	if (&user != this)
	{
		m_strName = user.m_strName;
		m_strPassword = user.m_strPassword;
		m_bAccountDisabled = user.m_bAccountDisabled;

		m_strHomeDirectory = user.m_strHomeDirectory;
		m_bAllowDownload = user.m_bAllowDownload;
		m_bAllowUpload = user.m_bAllowUpload;
		m_bAllowRename = user.m_bAllowRename;
		m_bAllowDelete = user.m_bAllowDelete;
		m_bAllowCreateDirectory = user.m_bAllowCreateDirectory;
	}
	return *this;
}


/********************************************************************/
/*																	*/
/* Function name : CUserManager										*/
/* Description   : Constructor										*/
/*																	*/
/********************************************************************/
CUserManager::CUserManager()
{
	GetAppDir(m_strFilename);
	m_strFilename += "users.dat";
}


/********************************************************************/
/*																	*/
/* Function name : ~CUserManager									*/
/* Description   : Destructor										*/
/*																	*/
/********************************************************************/
CUserManager::~CUserManager()
{

}


/********************************************************************/
/*																	*/
/* Function name : Serialize										*/
/* Description   : Call this function to store/load the user data	*/
/*																	*/
/********************************************************************/
BOOL CUserManager::Serialize(BOOL bStoring)
{
	static const TCHAR* lpszSignature = _T("Pablo Software Solutions - StoreObject");

	CFile file;

	if (file.Open(m_strFilename, bStoring ? CFile::modeWrite|CFile::modeCreate : CFile::modeRead))
	{
		TRY
		{
			CString str; 
			CArchive ar(&file, bStoring ? CArchive::store : CArchive::load);
			
			if (bStoring)
			{
				// save signature
				ar << CString(lpszSignature);

				// Save the changed user details
				for (int i=0; i < m_UserArray.GetSize(); i++)
				{
					m_UserArray[i].Serialize(ar);
				}

				ar.Flush();
			}
			else
			{
				// load signature
				ar >> str;
				// if this the file we are looking for ?
				if (str.Compare(lpszSignature) == 0)
				{
					int nCount=0;

					while(!ar.IsBufferEmpty())
					{
						CUser user;

						// get user data
						user.Serialize(ar);
						
						// add user to array
						m_UserArray.Add(user);
					}
				}
			}
			ar.Close();
			file.Close();
		}
		CATCH_ALL(e)
		{
			// catch all exceptions that might happen ...
			return FALSE;
		}
		END_CATCH_ALL
	}
	return TRUE;
}


/********************************************************************/
/*																	*/
/* Function name : GetUser											*/
/* Description   : Get user object for specified username			*/
/*																	*/
/********************************************************************/
BOOL CUserManager::GetUser(LPCTSTR lpszUser, CUser &user)
{
	m_CriticalSection.Lock();
	for (int i=0; i<m_UserArray.GetSize(); i++)
	{
		if (!m_UserArray[i].m_strName.CompareNoCase(lpszUser))
		{
			user = m_UserArray[i];
			m_CriticalSection.Unlock();
			return TRUE;
		}
	}
	m_CriticalSection.Unlock();
	return FALSE;
}


/********************************************************************/
/*																	*/
/* Function name : GetUserList										*/
/* Description   : Make copy of user array							*/
/*																	*/
/********************************************************************/
void CUserManager::GetUserList(CArray<CUser, CUser&>&array)
{
	m_CriticalSection.Lock();
	for (int i=0; i<m_UserArray.GetSize();i++)
	{
		array.Add(m_UserArray[i]);
	}
	m_CriticalSection.Unlock();
}


/********************************************************************/
/*																	*/
/* Function name : UpdateUserList									*/
/* Description   : Update user array								*/
/*																	*/
/********************************************************************/
void CUserManager::UpdateUserList(CArray<CUser, CUser&>&array)
{
	m_CriticalSection.Lock();
	m_UserArray.RemoveAll();
	for (int i=0; i<array.GetSize();i++)
	{
		m_UserArray.Add(array[i]);
	}
	m_CriticalSection.Unlock();
	Serialize(TRUE);
}


